import React, { useState, useRef, useEffect } from 'react';
import ReactMarkdown from 'react-markdown';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { vscDarkPlus } from 'react-syntax-highlighter/dist/esm/styles/prism';
import remarkGfm from 'remark-gfm';
import rehypeRaw from 'rehype-raw';
import { useUser } from '@contexts/UserContext';
import { useChat } from '@contexts/ChatContext';
import { sendMessage2Server as sendMessageOllama } from '@services/deepseek';
import { checkConfig } from '@services/config';
import { getCurrentTime } from '@utils/time';
import { formatFileSize } from '@utils/file';
import MessageBubble from '@components/MessageBubble';
import RenameModal from '@components/RenameModal';
import TextInput from '@components/TextInput';
import './styles.scss';
import FilePreviews from './FilePreviews';

// 导入图标资源
import fileIconPdf from '@assets/file-icon-pdf.svg';
import fileIconDoc from '@assets/file-icon-doc.svg';
import fileIconPpt from '@assets/file-icon-ppt.svg';
import fileIconCsv from '@assets/file-icon-csv.svg';
import fileIconImg from '@assets/file-icon-img.svg';
import logo from '@assets/logo.png';

/**
 * ChatArea 组件
 * 聊天区域的主要组件，负责消息的显示、发送和交互
 * 
 * @param {Object} props
 * @param {string} props.conversationTitle - 对话标题
 * @param {Function} props.setConversationTitle - 设置对话标题的回调函数
 */
const ChatArea = ({ conversationTitle, setConversationTitle }) => {
    // 状态管理
    const [messages, setMessages] = useState([]);
    const [inputValue, setInputValue] = useState('');
    const [isFocused, setIsFocused] = useState(false);
    const [activeQuickAction, setActiveQuickAction] = useState(null);
    const [isLoading, setIsLoading] = useState(false);
    const [isPaused, setIsPaused] = useState(false);
    const [isEditingTitle, setIsEditingTitle] = useState(false);
    const [tempTitle, setTempTitle] = useState(conversationTitle);
    const [selectedFiles, setSelectedFiles] = useState([]);
    const [showScrollButton, setShowScrollButton] = useState(false);
    const [showErrorToast, setShowErrorToast] = useState(false);

    // Refs
    const inputRef = useRef(null);
    const messagesEndRef = useRef(null);
    const chatMessagesRef = useRef(null);
    const fileInputRef = useRef(null);
    const abortControllerRef = useRef(null);
    const currentMessageRef = useRef(null);

    // Context
    const { generalChatMessages, updateGeneralChatMessages } = useChat();
    const { avatarUrl } = useUser();

    // 初始化消息，只在 generalChatMessages 变化时同步
    useEffect(() => {
        setMessages(
            generalChatMessages.length > 0
                ? generalChatMessages
                : [
                    {
                        id: '1',
                        content: '你好！我是 AI 助手，有什么我可以帮你的吗？',
                        role: 'assistant',
                        timestamp: getCurrentTime(),
                        avatar: logo,
                        name: 'AI Agent',
                    },
                    {
                        id: '2',
                        content: `<think>
好，我现在要回答关于泰勒级数的主要公式表达的问题。嗯，首先我记得泰勒级数是将一个函数展开成无限项的和，这些项涉及到函数在某一点处的各阶导数值。

那泰勒级数的一般形式应该是怎样的呢？好像是从n=0开始到无穷大的求和吧。对了，每一项都是关于(x - a)的幂次乘以相应的系数。系数应该包括n!，因为导数的阶数是n，然后除以n!可能是为了归一化。

所以公式应该是这样的：f(a) + f’(a)(x-a)/1! + f''(a)(x-a)^2/2! + ……一直到无穷大。也就是总和符号下，从n=0到∞，求f的n阶导数在a处的值乘以(x - a)^n再除以n!。

那是否还有另一种表达方式？我记得有时候会用Σ符号来表示这个无限级数，所以写成∑_{n=0}^{∞} [f^{(n)}(a) * (x - a)^n] / n! 会更简洁明了。对吗？

嗯，可能有些时候泰勒级数也被称为麦克劳林级数，当a=0的时候。但这里问的是主要公式，所以应该是通用的表达式，也就是以任意点a为中心展开的情况。

再想想有没有漏掉什么？比如收敛区间或者余项之类的，不过题目只要求主公式，不需要讨论收敛性或其他方面的问题。那么答案就是那个无限级数的形式了。
</think>
### **核心公式**
这是测试公式：

\\[
f(x) = \\sum_{n=0}^{\\infty} \\frac{f^{(n)}(a)}{n!} (x-a)^n
\\]
`,
                        role: 'assistant',
                        timestamp: getCurrentTime(),
                        avatar: logo,
                        name: '张三',
                    },
                ]
        );
    }, [generalChatMessages]);

    // DEBUG 监听 messages 变化
    useEffect(() => {
        console.log(messages);
    }, [messages]);

    // 监听滚动事件
    useEffect(() => {
        const handleScroll = () => {
            if (chatMessagesRef.current) {
                const { scrollTop, scrollHeight, clientHeight } = chatMessagesRef.current;
                setShowScrollButton(scrollHeight - scrollTop - clientHeight > 100);
            }
        };

        const messagesContainer = chatMessagesRef.current;
        if (messagesContainer) {
            messagesContainer.addEventListener('scroll', handleScroll);
            return () => messagesContainer.removeEventListener('scroll', handleScroll);
        }
    }, []);

    // 处理标题点击
    const handleTitleClick = () => {
        setTempTitle(conversationTitle);
        setIsEditingTitle(true);
    };

    // 处理关闭模态框
    const handleCloseModal = () => {
        setIsEditingTitle(false);
        setTempTitle(conversationTitle);
    };

    // 处理标题提交
    const handleTitleSubmit = () => {
        setConversationTitle(tempTitle);
        setIsEditingTitle(false);
    };

    // 处理标题变更
    const handleTitleChange = (value) => {
        setTempTitle(value);
    };

    // 处理快捷操作
    const handleQuickAction = (action) => {
        setActiveQuickAction(activeQuickAction === action ? null : action);
    };

    // 处理输入变更
    const handleInputChange = (e) => {
        setInputValue(e.target.value);
    };

    // 处理按键事件
    const handleKeyPress = (e) => {
        if (e.key === 'Enter' && !e.shiftKey) {
            e.preventDefault();
            handleSendMessage();
        }
    };

    // 处理文件选择
    const handleFileSelect = (event) => {
        const files = Array.from(event.target.files || []);
        if (files.length > 0) {
            if (selectedFiles.length + files.length > 10) {
                setShowErrorToast(true);
                setTimeout(() => setShowErrorToast(false), 3000);
                return;
            }

            files.forEach((file) => {
                let previewUrl;
                if (file.type.startsWith('image/')) {
                    previewUrl = URL.createObjectURL(file);
                }

                const fileState = {
                    id: Date.now() + '-' + Math.random().toString(36).substr(2, 9),
                    name: file.name,
                    type: file.type,
                    size: file.size,
                    lastModified: file.lastModified,
                    progress: 0,
                    status: 'uploading',
                    sizeFormatted: formatFileSize(file.size),
                    previewUrl: previewUrl,
                };

                setSelectedFiles((prev) => [...prev, fileState]);

                let progress = 0;
                const interval = setInterval(() => {
                    progress += 10;
                    if (progress <= 100) {
                        setSelectedFiles((prev) =>
                            prev.map((f) => {
                                if (f.id === fileState.id) {
                                    return {
                                        ...f,
                                        progress,
                                        status: progress === 100 ? 'success' : 'uploading',
                                    };
                                }
                                return f;
                            })
                        );
                    } else {
                        clearInterval(interval);
                    }
                }, 300);
            });
        }
    };

    // 处理移除文件
    const handleRemoveFile = (fileId) => {
        setSelectedFiles((prev) => {
            const file = prev.find((f) => f.id === fileId);
            if (file?.previewUrl) {
                URL.revokeObjectURL(file.previewUrl);
            }
            return prev.filter((f) => f.id !== fileId);
        });
    };

    // 滚动到底部
    const scrollToBottom = () => {
        if (chatMessagesRef.current) {
            chatMessagesRef.current.scrollTo({
                top: chatMessagesRef.current.scrollHeight,
                behavior: 'smooth',
            });
        }
    };

    // 处理发送消息
    const handleSendMessage = async () => {
        if (inputValue.trim() || selectedFiles.length > 0) {
            if (abortControllerRef.current) {
                abortControllerRef.current.abort();
                abortControllerRef.current = null;
                setIsLoading(false);
                setIsPaused(false);
            }

            const userMessage = {
                id: Date.now().toString(),
                content: inputValue.trim(),
                files: selectedFiles,
                role: 'user',
                timestamp: getCurrentTime(),
                name: '我',
                avatar: avatarUrl,
            };

            // 如果是第一条用户消息，设置为对话标题
            const isFirstUserMessage = !messages.some((msg) => msg.role === 'user');
            if (isFirstUserMessage) {
                if (!inputValue.trim() && selectedFiles.length > 0) {
                    setConversationTitle(selectedFiles[0].name);
                } else {
                    const titleText = inputValue.trim();
                    setConversationTitle(
                        titleText.length > 20 ? titleText.substring(0, 20) + '...' : titleText
                    );
                }
            }

            setMessages((prev) => {
                const newMessages = [...prev, userMessage];
                updateGeneralChatMessages(newMessages);
                return newMessages;
            });
            setInputValue('');
            setSelectedFiles([]);

            const aiMessage = {
                id: (Date.now() + 1).toString(),
                content: '正在思考...',
                role: 'assistant',
                timestamp: getCurrentTime(),
                avatar: logo,
                name: 'AI Agent',
            };

            try {
                setMessages((prev) => {
                    const newMessages = [...prev, aiMessage];
                    updateGeneralChatMessages(newMessages);
                    return newMessages;
                });
                currentMessageRef.current = aiMessage;

                abortControllerRef.current = new AbortController();
                setIsLoading(true);

                // 构建发送给 AI 的消息内容
                let messageContent = inputValue.trim();
                if (selectedFiles.length > 0) {
                    const filesInfo = selectedFiles
                        .map((file) => `${file.name} (${file.sizeFormatted})`)
                        .join('\n');
                    messageContent = messageContent
                        ? `${messageContent}\n\n附件列表：\n${filesInfo}`
                        : `请查看以下文件：\n${filesInfo}`;
                }

                await sendMessageOllama(
                    messageContent,
                    (text) => {
                        if (!isPaused) {
                            setMessages((prev) => {
                                const updated = prev.map((msg) =>
                                    msg.id === aiMessage.id ? { ...msg, content: text } : msg
                                );
                                updateGeneralChatMessages(updated);
                                return updated;
                            });
                        }
                    },
                    process.env.REACT_APP_OLLAMA_STREAM_RESPONSE === 'true',
                    abortControllerRef.current
                );
            } catch (error) {
                console.error('Error:', error);
                if (error instanceof Error && error.name === 'AbortError') {
                    return;
                }
                setMessages((prev) => {
                    const updated = prev.map((msg) =>
                        msg.id === aiMessage.id
                            ? {
                                ...msg,
                                content: `错误信息: ${error instanceof Error ? error.message : '未知错误'
                                    }`,
                            }
                            : msg
                    );
                    updateGeneralChatMessages(updated);
                    return updated;
                });
            } finally {
                if (!isPaused) {
                    setIsLoading(false);
                }
                abortControllerRef.current = null;
                currentMessageRef.current = null;
                if (inputRef.current) {
                    inputRef.current.focus();
                }
            }
        }
    };

    // 处理暂停生成
    const handlePauseGeneration = () => {
        if (abortControllerRef.current) {
            abortControllerRef.current.abort();
            setIsPaused(true);
            setIsLoading(true);
            setMessages((prev) => {
                const lastMessage = prev[prev.length - 1];
                if (lastMessage && lastMessage.role === 'assistant') {
                    return prev.map((msg) =>
                        msg.id === lastMessage.id
                            ? { ...msg, content: msg.content + '\n\n[已暂停]' }
                            : msg
                    );
                }
                return prev;
            });
            setIsPaused(false);
        }
    };

    // 处理恢复生成
    const handleResumeGeneration = async () => {
        if (currentMessageRef.current) {
            setIsPaused(false);
            setIsLoading(true);
            try {
                abortControllerRef.current = new AbortController();
                await sendMessageOllama(
                    currentMessageRef.current.content,
                    (text) => {
                        if (!isPaused) {
                            setMessages((prev) =>
                                prev.map((msg) =>
                                    msg.id === currentMessageRef.current?.id
                                        ? { ...msg, content: text }
                                        : msg
                                )
                            );
                        }
                    },
                    process.env.REACT_APP_OLLAMA_STREAM_RESPONSE === 'true',
                    abortControllerRef.current
                );
            } catch (error) {
                console.error('Error resuming generation:', error);
            } finally {
                if (!isPaused) {
                    setIsLoading(false);
                }
                abortControllerRef.current = null;
            }
        }
    };

    // 根据文件类型获取对应的图标
    const getFileIcon = (file) => {
        if (!file) return fileIconDoc;

        const fileName = file.name?.toLowerCase() || '';
        const fileType = file.type || '';

        if (fileType.toLowerCase().startsWith('image/')) {
            return fileIconImg;
        }

        if (
            fileType.toLowerCase() === 'application/pdf' ||
            fileName.endsWith('.pdf')
        ) {
            return fileIconPdf;
        }

        if (
            fileType.toLowerCase() === 'application/msword' ||
            fileType.toLowerCase() ===
            'application/vnd.openxmlformats-officedocument.wordprocessingml.document' ||
            /\.(doc|docx)$/i.test(fileName)
        ) {
            return fileIconDoc;
        }

        if (
            fileType.toLowerCase() === 'application/vnd.ms-excel' ||
            fileType.toLowerCase() ===
            'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ||
            fileType.toLowerCase() === 'text/csv' ||
            /\.(xls|xlsx|csv)$/i.test(fileName)
        ) {
            return fileIconCsv;
        }

        if (
            fileType.toLowerCase() === 'application/vnd.ms-powerpoint' ||
            fileType.toLowerCase() ===
            'application/vnd.openxmlformats-officedocument.presentationml.presentation' ||
            /\.(ppt|pptx)$/i.test(fileName)
        ) {
            return fileIconPpt;
        }

        return fileIconDoc;
    };

    // 处理用户消息编辑
    const handleUserMessageEdit = (messageId) => {
        console.log('handleUserMessageEdit', messageId);
    }

    // 处理用户消息复制
    const handleUserMessageCopy = (messageId) => {
        console.log('handleUserMessageCopy', messageId);
        const message = messages.find(message => message.id === messageId);
        if (message) {
            navigator.clipboard.writeText(message.content);
        }
    }

    // 处理用户消息分享
    const handleUserMessageShare = (messageId) => {
        console.log('handleUserMessageShare', messageId);
    }   

    // 处理用户消息更多
    const handleUserMessageMore = (messageId) => {
        console.log('handleUserMessageMore', messageId);
    }

    // 处理助手消息语音播放
    const handleAssistantMessageVoice = (messageId) => {
        console.log('handleAssistantMessageVoice', messageId);
    }   

    // 处理助手消息复制
    const handleAssistantMessageCopy = (messageId) => {
        console.log('handleAssistantMessageCopy', messageId);
    }       

    // 处理助手消息重新生成
    const handleAssistantMessageRegenerate = (messageId) => {
        console.log('handleAssistantMessageRegenerate', messageId);
    }

    // 处理助手消息分享
    const handleAssistantMessageShare = (messageId) => {
        console.log('handleAssistantMessageShare', messageId);
    }

    // 处理助手消息更多
    const handleAssistantMessageMore = (messageId) => {
        console.log('handleAssistantMessageMore', messageId);
    }

    // 处理助手消息点赞
    const handleAssistantMessageLike = (messageId) => {
        console.log('handleAssistantMessageLike', messageId);
    }

    // 处理助手消息点踩
    const handleAssistantMessageDislike = (messageId) => {
        console.log('handleAssistantMessageDislike', messageId);
    }


    return (
        <div className="chat-area">
            {showErrorToast && (
                <div className="chat-area__error-toast">
                    <i className="ri-error-warning-line" />
                    <span>最多只能上传 10 个文件</span>
                </div>
            )}
            <div className="chat-area__content">
                <div className="chat-area__header">
                    <div className="chat-area__header-wrapper">
                        <div className="chat-area__header-title" onClick={handleTitleClick}>
                            {conversationTitle}
                            <i className="ri-edit-line edit-icon" />
                        </div>
                    </div>
                </div>

                <RenameModal
                    isOpen={isEditingTitle}
                    title="修改对话标题"
                    value={tempTitle}
                    onClose={handleCloseModal}
                    onSubmit={handleTitleSubmit}
                    onChange={handleTitleChange}
                    placeholder="请输入新的标题"
                />

                <div className="chat-area__messages" ref={chatMessagesRef}>
                    {messages.map((message) => (
                        <MessageBubble
                            key={message.id}
                            message={message}
                            getFileIcon={getFileIcon}
                            handleUserMessageEdit={handleUserMessageEdit}
                            handleUserMessageCopy={handleUserMessageCopy}
                            handleUserMessageShare={handleUserMessageShare}
                            handleUserMessageMore={handleUserMessageMore}
                            handleAssistantMessageVoice={handleAssistantMessageVoice}
                            handleAssistantMessageCopy={handleAssistantMessageCopy}
                            handleAssistantMessageRegenerate={handleAssistantMessageRegenerate}
                            handleAssistantMessageShare={handleAssistantMessageShare}
                            handleAssistantMessageMore={handleAssistantMessageMore}
                            handleAssistantMessageLike={handleAssistantMessageLike}
                            handleAssistantMessageDislike={handleAssistantMessageDislike}
                        />
                    ))}
                    <div ref={messagesEndRef} />
                </div>

                <div className="chat-area__input-area">
                    <button
                        className={`chat-area__scroll-button ${showScrollButton ? 'chat-area__scroll-button--visible' : ''
                            }`}
                        onClick={scrollToBottom}
                    >
                        <i className="ri-arrow-down-s-line" />
                    </button>

                    <div className="chat-area__quick-actions">
                        <button
                            className={`chat-area__quick-action ${activeQuickAction === 'function1'
                                ? 'chat-area__quick-action--active'
                                : ''
                                }`}
                            onClick={() => handleQuickAction('function1')}
                        >
                            <i className="ri-code-line" />
                            快捷功能
                        </button>
                        <button
                            className={`chat-area__quick-action ${activeQuickAction === 'function2'
                                ? 'chat-area__quick-action--active'
                                : ''
                                }`}
                            onClick={() => handleQuickAction('function2')}
                        >
                            <i className="ri-code-line" />
                            快捷功能
                        </button>
                    </div>

                    <div
                        className={`chat-area__input-area-container ${isFocused ? 'chat-area__input-area-container--focused' : ''
                            }`}
                    >
                        {selectedFiles.length > 0 && (
                            <FilePreviews files={selectedFiles} getFileIcon={getFileIcon} canRemove={true} handleRemoveFile={handleRemoveFile} />
                        )}
                        <textarea
                            ref={inputRef}
                            className="chat-area__input-area-input"
                            value={inputValue}
                            onChange={handleInputChange}
                            onFocus={() => setIsFocused(true)}
                            onBlur={() => setIsFocused(false)}
                            onKeyPress={handleKeyPress}
                            placeholder="给AI Agent发消息"
                            rows={1}
                        />
                        <div className="chat-area__input-area-actions">
                            <div className="chat-area__input-area-buttons">
                                <input
                                    type="file"
                                    ref={fileInputRef}
                                    onChange={handleFileSelect}
                                    style={{ display: 'none' }}
                                    accept=".pdf,.doc,.docx,.xls,.xlsx,.jpg,.jpeg,.png"
                                    multiple
                                />
                                <button
                                    className="chat-area__action-button"
                                    onClick={() => fileInputRef.current?.click()}
                                    style={{ opacity: selectedFiles.length >= 10 ? 0.5 : 1 }}
                                    disabled={selectedFiles.length >= 10}
                                >
                                    <i className="ri-attachment-2" />
                                </button>
                                <button className="chat-area__action-button">
                                    <i className="ri-mic-line" />
                                </button>
                            </div>
                            {isLoading ? (
                                isPaused ? (
                                    <button
                                        className="chat-area__send-button chat-area__send-button--disabled opacity-50"
                                        disabled={true}
                                        style={{
                                            opacity: 0.5
                                        }}
                                    >
                                        <i className="ri-send-plane-fill" />
                                    </button>
                                ) : (
                                    <button
                                        className="chat-area__send-button opacity-100"
                                        onClick={handlePauseGeneration}
                                        style={{
                                            opacity: 1
                                        }}
                                    >
                                        <i className="ri-pause-fill" />
                                    </button>
                                )
                            ) : (
                                <button
                                    className={`chat-area__send-button ${inputValue.trim()&&selectedFiles.length==0 || selectedFiles.length > 0 && selectedFiles.every(file => file.status === 'success') ? 'opacity-100' : 'opacity-50'}`}
                                    onClick={handleSendMessage}
                                    style={{
                                        opacity:
                                            inputValue.trim()&&selectedFiles.length==0 || selectedFiles.length > 0 && selectedFiles.every(file => file.status === 'success') ? 1 : 0.5,
                                    }}
                                >
                                    <i className="ri-send-plane-fill" />
                                </button>
                            )}
                        </div>
                    </div>
                </div>
            </div>
        </div>
    );
};

export default ChatArea; 